var _ = require('lodash')
class ConfigHandler {
  constructor(config,width) {
    this.config = _.cloneDeep(this.mergeConfig(config));
    this.specCategory = {};
    this.width = width
    this.columnTreeModelName = 'column_tree_model';
  }

  initializeStore() {
    let {store_fields} = this.handle();
    // debugger
    let modelName = 'column_tree_model'
    Ext.define(modelName, {
      extend: "Ext.data.Model",
      fields: store_fields
    });
    let configStore = Ext.create("Ext.data.Store", {
      autoLoad: false,
      model: modelName,
      data: []
    });
    return configStore;
  }

  mergeConfig(config){
    let _spec_category = _.cloneDeep(config)
    let __spec_category = {};
    _spec_category.forEach(el=>{
      if(!__spec_category[el.name]){
        __spec_category[el.name] = {}
      }
      let i = __spec_category[el.name].spec_array
      if(!i){
        i = [];
      }
      i = i.concat(el.spec_array)
      __spec_category[el.name].spec_array = i
      __spec_category[el.name].name = el.name
      __spec_category[el.name].en_name = el.en_name
      __spec_category[el.name].memo = el.memo
      __spec_category[el.name].en_memo = el.en_memo
      __spec_category[el.name].sort = el.sort
    })
    return Object.keys(__spec_category).map(key => {

      let el = __spec_category[key],
        sp = el.spec_array,
        name = el.name

      // sp.forEach(sp => {
      //   if (!sp.group_label) {
      //     throw new Error(`属性 ${name} 的 ${sp.name} ${PSI.Const.Z_GOOD_SPEC_MODEL.GROUP_LABEL}不能为空`)
      //   }
      // })
      return el
    });
  }

  initGroups(mr){
    return  mr.map(el => {
      let spec_array = el.spec_array,
        groups = []
      spec_array.forEach(sp => {
        let group_index = -1;
        // if (PSI.Utils.hasUnderScore(sp.group_label)) {
        //   throw new Error(`${PSI.Const.Z_GOOD_SPEC_MODEL.GROUP_LABEL} ${sp.group_label} 不能含_`)
        // }
        // if (PSI.Utils.hasUnderScore(sp.group_label)) {
        //   throw new Error(`${PSI.Const.Z_GOOD_SPEC_MODEL.GROUP_LABEL} ${sp.group_label} 不能含_`)
        // }

        // if (PSI.Utils.hasUnderScore(sp.name)) {
        //   throw new Error(`${PSI.Const.Z_GOOD_SPEC_MODEL.NAME} ${sp.name} 不能含_`)
        // }
        // if (PSI.Utils.hasUnderScore(sp.name) && sp.name !== '*') {
        //   throw new Error(`${PSI.Const.Z_GOOD_SPEC_MODEL.NAME} ${sp.name} 不能含_`)
        // }
        groups.forEach((g, index) => {
          if (g.name == sp.group_label) {
            group_index = index
          }
        })
        if (group_index === -1) {
          groups.push({
            name: sp.group_label,
            items: [sp]
          })
        } else {
          let g = groups[group_index];
          g.items.push(sp)
          groups[group_index] = g
        }
      })

      el.group_count = groups.length

      // el.set('group_count',groups.length)

      return groups.map(g => {
        return {
          text: g.name,
          values: g.items.map(i => i.name).join('/')
        }
      })
    })

  }

  doubleColumns2(rr, columns_need_double) {


    let levels = [];
    columns_need_double.forEach(el => {
      let depth = el[0];
      if (levels.indexOf(depth) < 0) {
        levels.push(depth)
      }
    })
    // debugger
    levels = levels.map(l => {
      let c = [];
      columns_need_double.forEach(el => {
        let depth = el[0],
          replace_header = el[1];
        if (depth === l) {
          c.push(replace_header)
        }
      })
      return {depth: l, items: c}
    })
    let res = _.cloneDeep(rr)
    // debugger
    levels.forEach(cc => {

      let bk = res;
      let depth = cc.depth
      cc.items.forEach(c => {
        let replace_header = c
        res.forEach(r => {
          let copy_column = _.cloneDeep(r),

            l = 0
          // debugger
          let t = copy_column
          while (true) {

            // debugger

            if (t && t.columns) {
              // debugger

              let b = t;
              if (l === depth) {
                b.text = replace_header.text
                b.values = replace_header.values
                break
              }
              t = t.columns[0]
              l++

            }
          }
          bk = bk.concat([copy_column])
        })
      })
      res = bk
    })
    // debugger

    return res
  }

  generateFieldByColumnTree(column_tree, map) {
    //_1_,_2_,_3_
    let map_len = Object.keys(map).length
    let level = 1,
      cs = column_tree,
      field = [],
      q = []
    // debugger
    if (map_len > 1) {
      for (let i = 0; i < map_len; i++) {
        if (!cs) {
          break
        }
        if (cs.values) {
          let value_arr = cs.values.split('/').map(t => {
            return t.replace(/\./g, "dot");
          })
          // debugger
          let text = _.cloneDeep(value_arr).sort().join('_')
          text = [map[level - 1], text].join('__')
          field.push(text)
          // debugger
        }

        level++
        if (i === map_len - 2) {
          // debugger
          cs.columns.forEach(n => {

            let saved_field = _.cloneDeep(field);
            let value_arr = n.values.split('/').map(t => {
              return t.replace(/\./g, "dot");
            })
            // debugger
            let text = _.cloneDeep(value_arr).sort().join('_')
            text = [map[level - 1], text].join('__')
            saved_field.push(text)
            q.push(saved_field.join('___'))
          })
          // debugger
        }
        if (cs.columns) {
          cs = cs.columns[0]
        } else {
          cs = null
        }

      }
    } else {
      for (let i = 0; i < map_len; i++) {
        if (cs.values) {
          let value_arr = cs.values.split('/').map(t => {
            return t.replace(/\./g, "dot");
          })
          let text = _.cloneDeep(value_arr).sort().join('_')
          text = [map[level - 1], text].join('__')
          field.push(text)
          // debugger
          q.push(text)
        }
      }
    }

    return q
  }

  handle() {
    let _spec_category = _.cloneDeep(this.config);
    let __spec_category = {};
    _spec_category.forEach((el) => {
      if (!__spec_category[el.name]) {
        __spec_category[el.name] = {};
      }
      let i = __spec_category[el.name].spec_array;
      if (!i) {
        i = [];
      }
      i = i.concat(el.spec_array);
      __spec_category[el.name].spec_array = i;
      __spec_category[el.name].name = el.name;
      __spec_category[el.name].en_name = el.en_name;
      __spec_category[el.name].memo = el.memo;
      __spec_category[el.name].en_memo = el.en_memo;
      __spec_category[el.name].sort = el.sort;
    });

    let mr = Object.keys(__spec_category).map((key) => {
      let el = __spec_category[key],
        sp = el.spec_array,
        name = el.name;

      sp.forEach((sp) => {
        if (!sp.group_label) {
          // throw new Error(`属性 ${name} 的 ${sp.name} ${PSI.Const.Z_GOOD_SPEC_MODEL.GROUP_LABEL}不能为空`);
        }
      });
      return el;
    });

    let configGroup = this.initGroups(mr)
    // debugger
    // Sort configGroup
    const sortedArray = _.cloneDeep(configGroup.sort((a, b) => a.length - b.length));

    const levelPropertyMap = {};
    let column_a = mr.map((el) => ({
      text: el.name,
      group_count: el.group_count,
      align: 'center',
      width: 80,
      sortable: false,
      dataIndex: 'price_label',
    })).sort((a, b) => a.group_count - b.group_count).map((el, index) => {
      // debugger
      levelPropertyMap[index] = el.text;
      return el;
    }).reverse().reduce((accumulator, currentValue) => {
      currentValue.columns = [accumulator];
      return currentValue;
    });

    let columnConfig = [];
    let tempCol = [];
    let columnsNeedDouble = [];
    let configGroupLength = configGroup.length;
    let level1ColumnCount = 1;

    // debugger
    sortedArray.forEach((group, index) => {
      // debugger
      if (index < configGroupLength - 1) {
        level1ColumnCount = level1ColumnCount * group.length;

        if (group.length > 1) {
          for (let i = 1; i < group.length; i++) {
            columnsNeedDouble.push([index, group[i]]);
          }
        }
      }

      let item = group[0];

      if (index < configGroupLength - 1) {
        let q = _.cloneDeep(item);
        tempCol.push(q);
      } else {
        tempCol.push(group);
      }
    });

    let firstConfigColumn = [];

    if (tempCol.length > 1) {
      firstConfigColumn = tempCol.reverse().reduce((accumulator, currentValue) => {
        let c = _.cloneDeep(accumulator);

        if (Array.isArray(accumulator)) {
          let sortedItem = _.cloneDeep(accumulator).map((el) => el.text).sort();

          sortedItem = sortedItem.map((el) => {
            let idx = 0;
            for (let i = 0; i < c.length; i++) {
              if (accumulator[i].text === el) {
                idx = i;
                break;
              }
            }

            return accumulator[idx];
          });

          accumulator = sortedItem.map((e) => {
            e.align = 'center';
            e.sortable = false;
            e.width = this.width;
            e.flex = 1;
            return e;
          });
        }

        currentValue.align = 'center';
        currentValue.width = this.width;
        currentValue.sortable = false;
        currentValue.flex = 1;
        currentValue.columns = Array.isArray(accumulator) ? accumulator : [accumulator];
        return currentValue;
      });

      columnConfig = this.doubleColumns2([firstConfigColumn], columnsNeedDouble);
      // debugger
    } else {
      // debugger
      if (Array.isArray(tempCol[0])) {
        columnConfig = tempCol[0].map((el) =>  {

          return {
            text: el.text,
            align: 'center',
            sortable: false,
            width :this.width,
            flex: 1,
            values:el.values
          }
        });
      } else {
        columnConfig = [];
      }
    }

    // debugger


    let storeFields = ['price_label'];
    let fields = [],
      fields2 = []
    let fields_headers_level_map = {};
    columnConfig.forEach((el) => {
      let field = this.generateFieldByColumnTree(el, levelPropertyMap);

      // debugger
      // const el_fields = [...storeFields, ...field];
      const el_fields =[];
      const el_fields2 =[];

      // debugger


      let l = Object.keys(levelPropertyMap).length,
        t = el,
        header_level_map = [[levelPropertyMap[0],el.text].join(':')],
        header_level_map2 = [el.text];
      if (l === 1) {
        el.editor = {
          xtype: 'numberfield',
          hideTrigger: true,
        };
        el.renderer = function (_val){
          if(_val > -1){
            return `<span style="color: blue">${_val}</span>`
          }else {
            return `<span style="color: red">${_val}</span>`
          }
        }
        fields_headers_level_map[field[0]] = header_level_map.join('_')
        const replaced_header = _.cloneDeep(header_level_map).sort().join('_').replace(/\./g, "dot");
        el.dataIndex = replaced_header
        el_fields.push(replaced_header)
        el_fields2.push(_.cloneDeep(header_level_map2).sort().join('_').replace(/\./g, "dot"))
      } else {
        for (let i = 0; i < l; i++) {
          if (i === l - 2) {
            t.columns.forEach((c, index) => {
              c.editor = {
                xtype: 'numberfield',
                hideTrigger: true,
              };

              c.renderer = function (_val){
                if(_val > -1){
                  return `<span style="color: blue">${_val}</span>`
                }else {
                  return `<span style="color: red">${_val}</span>`
                }
              }
              header_level_map.push([levelPropertyMap[i+1],c.text].join(':'))
              header_level_map2.push(c.text)
              fields_headers_level_map[field[index]] = header_level_map.join('_')
              const replaced_header = _.cloneDeep(header_level_map).sort().join('_').replace(/\./g, "dot");
              c.dataIndex = replaced_header
              el_fields.push(replaced_header)
              el_fields2.push(_.cloneDeep(header_level_map2).sort().join('_').replace(/\./g, "dot"))
              header_level_map.pop()
              header_level_map2.pop()

            });
          }
          if (t.columns) {
            t = t.columns[0];
            header_level_map.push([levelPropertyMap[i+1],t.text].join(':'))
            header_level_map2.push(t.text)
          }
        }
      }
      // debugger
      fields.push([...el_fields,...storeFields])
      fields2.push([...el_fields2,...storeFields])
    });
    // debugger


    let column_list = columnConfig.map((el,index)=>{
      const label = this.treeToList(el);
      const price_store_fields = fields[index]
      const price_store_fields_old = fields2[index]
      const columns = [column_a,el]
      const store = []
      store.push(price_store_fields.reduce((ac,cur)=>{
        if(cur == 'price_label'){
          ac[cur] = '销售价'
        }else{
          ac[cur] = null
        }
        return ac
      },{}))
      return {columns,label,price_store_fields,store,price_store_fields_old}
    });
    return {column_list};
  }

  treeToList(tree){
    let r = []
    r.push(tree.text)
    if(tree.columns && tree.columns.length === 1){
      tree.columns.forEach(e=>{
        r = r.concat(this.treeToList(e))
      })
    }
    return r

  }

}


// Access the result like result.configStore and result.column_a


// Access the result like result.configStore and result.column_a


module.exports = ConfigHandler

// Access the result like result.configStore and result.column_a
